<?php
namespace app\services;

use app\common\model\Gamelist;
use app\common\model\Order;
use app\common\model\Stat as StatModel;
use app\common\model\Player;
use app\common\model\Channel;
use app\common\model\PlayerRole;
use app\common\model\Gameagent as GameAgent;
use app\common\model\Gameulog;
use think\Db;

class Stat
{
    /**
     * 执行统计
     * @return array
     */
    public function stat()
    {
        $statModel = new StatModel();
        $lastStatDate = $statModel->getLastStatDate();

        // 如果没有统计记录，默认从30天前开始统计
        $startTime = $lastStatDate ? strtotime($lastStatDate['stat_date']) - 86400 : strtotime('-94 days');
        $endTime = strtotime('today 23:59:59');

        // 获取需要统计的日期范围
        $datesToStat = $this->getDatesToStat($startTime, $endTime);


        $results = [];
        foreach ($datesToStat as $date) {

            $time = strtotime($date);
            $dailyStat = $this->getDailyStat($time);
            foreach ($dailyStat as $item) {
                $statModel->updateStat($item);
            }

            $results[$date] = $dailyStat;
        }

        return $results;
    }

    /**
     * 获取需要统计的日期范围
     * @param int $startTime 开始时间戳
     * @param int $endTime 结束时间戳
     * @return array
     */
    protected function getDatesToStat($startTime, $endTime)
    {
        $dates = [];
        for ($time = $startTime; $time <= $endTime; $time += 86400) {
            $dates[] = date('Y-m-d', $time);
        }
        return $dates;
    }

    /**
     * 获取每日统计
     * @param int $time 时间戳
     * @return array
     */
    protected function getDailyStat($time)
    {
        $startTime = strtotime('midnight', $time);
        $endTime = strtotime('tomorrow', $startTime) - 1;
        $date = date('Y-m-d', $startTime);

        $channels = Channel::where(["status"=>1])->column('id');
        array_unshift($channels, 0);
        $gameAgents = Gamelist::whereIn('gstatus', [1])// 1 上线 2 测试中
            ->field('DISTINCT id')
            ->select();
        $gameAgents = array_column($gameAgents->toArray(), 'id');

        $stats = [];
        foreach ($channels as $cid){
            foreach ($gameAgents as $gid) {
                $playerStat = $this->getPlayerStat($cid, $gid, $startTime, $endTime);
                $orderStat = $this->getOrderStat($cid, $gid, $startTime, $endTime);

                $activeUsers = $playerStat['active_users'] ?? 0;
                $payAmount = $orderStat['pay_amount'] ?? 0;
                $payUsers = $orderStat['pay_users'] ?? 0;

                $arpu = $activeUsers > 0 ? round($payAmount / $activeUsers, 2) : 0;
                $arppu = $payUsers > 0 ? round($payAmount / $payUsers, 2) : 0;

                $statData = [
                    'cid' => $cid,
                    'gid' => $gid,
                    'stat_date' => $date,
                    'new_users' => $playerStat['new_users'] ?? 0,
                    'new_roles' => $playerStat['new_roles'] ?? 0,
                    'active_users' => $activeUsers,
                    'pay_amount' => $payAmount,
                    'pay_users' => $payUsers,
                    'pay_times' => $orderStat['pay_times'] ?? 0,
                    'arpu' => $arpu,
                    'arppu' => $arppu,
                    'create_time' => time()
                ];

                // 检查是否所有统计指标都为0
                if (!$this->isAllZero($statData)) {
                    $stats[] = $statData;
                }
            }
        }


        return $stats;
    }

    /**
     * 判断统计结果是否全部为0
     * @param array $statData
     * @return bool
     */
    protected function isAllZero(array $statData): bool
    {
        $checkFields = [
            'new_users',
            'new_roles',
            'active_users',
            'pay_amount',
            'pay_users',
            'pay_times'
        ];

        foreach ($checkFields as $field) {
            if (!empty($statData[$field])) {
                return false;
            }
        }

        return true;
    }

    /**
     * 获取玩家统计（使用登录日志表统计活跃用户）
     * @param int $cid 渠道ID(0表示系统用户)
     * @param int $gid 游戏ID
     * @param int $startTime 开始时间戳(当天00:00:00)
     * @param int $endTime 结束时间戳(当天23:59:59)
     * @return array
     */
    protected function getPlayerStat($cid, $gid, $startTime, $endTime)
    {
        // 新增用户数（从玩家表统计）
        $newUsers = Player::where('gid', $gid)
            ->where('cid', $cid)
            ->whereBetween('create_time', [$startTime, $endTime])
            ->count('id');
        // 新增角色数（从角色表统计）
        $newRoles = PlayerRole::where('gid', $gid)
            ->where('cid', $cid)
            ->whereBetween('create_time', [date('Y-m-d H:i:s', $startTime), date('Y-m-d H:i:s', $endTime)])
            ->count('id');

        // 活跃用户数（从登录日志表统计，type=0表示登录记录）
        $activeUsers = Gameulog::where('gid', $gid)
            ->where('cid', $cid)
            ->where('type', 0)
            ->whereBetween('login_time', [$startTime, $endTime])
            ->group('uid')
            ->count();

        return [
            'new_users' => $newUsers ?: 0,
            'new_roles' => $newRoles ?: 0,
            'active_users' => $activeUsers ?: 0
        ];
    }

    /**
     * 获取订单统计
     * @param int $cid 渠道ID(0表示系统用户)
     * @param int $gid 游戏ID
     * @param int $startTime 开始时间戳(当天00:00:00)
     * @param int $endTime 结束时间戳(当天23:59:59)
     * @return array
     */
    protected function getOrderStat($cid, $gid, $startTime, $endTime)
    {
        // 使用模型的数据库连接
        $orderModel = new Order();

        // 付费总金额
        $payAmount = $orderModel->where('gid', $gid)
            ->where('cid', $cid)
            ->where('order_status', '>', 0)
            ->whereBetweenTime('pay_time', date('Y-m-d H:i:s', $startTime), date('Y-m-d H:i:s', $endTime))
            ->sum('amount');
        // 付费人数(去重)
        $payUsers = $orderModel->where('gid', $gid)
            ->where('cid', $cid)
            ->where('order_status', '>', 0)
            ->whereBetweenTime('pay_time', date('Y-m-d H:i:s', $startTime), date('Y-m-d H:i:s', $endTime))
            ->group('uid')
            ->count();

        // 付费次数
        $payTimes = $orderModel->where('gid', $gid)
            ->where('cid', $cid)
            ->where('order_status', '>', 0)
            ->whereBetweenTime('pay_time', date('Y-m-d H:i:s', $startTime), date('Y-m-d H:i:s', $endTime))
            ->count();

        return [
            'pay_amount' => $payAmount ?: 0,
            'pay_users' => $payUsers ?: 0,
            'pay_times' => $payTimes ?: 0
        ];
    }
}